package com.gxc.interceptors;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.Collection;
import java.util.Enumeration;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

/**
 * RequestInterceptor.
 *
 * @author 宫新程
 * @since 2018/12/29 1:35 PM
 */
@Slf4j
public class RequestInterceptor implements HandlerInterceptor {

  private static final String APPLICATION_JSON = "application/json";

  @Override
  public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
      throws Exception {
    // 打印请求消息头 & URL.
    this.printRequestHeader(request);
    // 打印请求request中的消息体
    this.printRequestBody(request);
    // 获取url 或者 请求参数键值对.
    this.printRequestParam(request);
    return true;
  }

  /** 打印请求request中的消息体. */
  private void printRequestBody(HttpServletRequest request) throws IOException {
    System.out.println("=======================================");
    System.out.println("请求消息体：");
    // POST请求提交JSON串，判断 content-type 类型
    String method = request.getMethod();
    String contentType = request.getHeader("content-type");
    if (method.equalsIgnoreCase("POST") && contentType.contains(APPLICATION_JSON)) {
      // 如果 content-type：application/json 使用流获取
      ServletInputStream inputStream = request.getInputStream();
      BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
      String requestBody = reader.lines().collect(Collectors.joining());
      System.out.println("请求消息体为：" + requestBody);
    }
  }

  /** 获取url 或者 请求参数键值对. */
  private void printRequestParam(HttpServletRequest request) {
    System.out.println("=======================================");
    System.out.println("请求入参为：");
    Map<String, String[]> parameterMap = request.getParameterMap();
    parameterMap.forEach(
        (k, v) -> {
          System.out.print("Key：" + k + "Value：");
          Arrays.stream(v).forEach(System.out::println);
        });
  }

  /** 打印请求消息头. */
  private void printRequestHeader(HttpServletRequest request) {
    System.out.println("=======================================");
    System.out.println("请求消息头为：");
    String url = request.getRequestURL().toString();
    System.out.println("URL：" + url);
    // 获取请求消息头.
    Enumeration<String> headerNames = request.getHeaderNames();
    while (headerNames.hasMoreElements()) {
      String header = headerNames.nextElement();
      String headerValue = request.getHeader(header);
      System.out.println(header + "：" + headerValue);
    }
  }

  @Override
  public void postHandle(
      HttpServletRequest request,
      HttpServletResponse response,
      Object handler,
      ModelAndView modelAndView)
      throws Exception {
    System.out.println("相应消息头为：");
    /** 相应消息头. */
    Collection<String> headerNames = response.getHeaderNames();
    headerNames.forEach(e -> System.out.println(e + "：" + response.getHeader(e)));
  }

  @Override
  public void afterCompletion(
      HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
      throws Exception {}
}
